package process.module;

import java.util.ArrayList;
import java.util.List;

import process.model.OntoResource;

import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

import core.constant.SystemConstant;

/**
 * @author tvo35
 * 
 */

public class OntoQuery {
	private OntModel m;

	public OntoQuery() {
		m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		FileManager.get().resetCache();
		FileManager.get().readModel(m, SystemConstant.O_FILE);
	}

	public List<OntoResource> getAllInstance() {
		List<OntoResource> list = new ArrayList<OntoResource>();
		ExtendedIterator<Individual> individuals = m.listIndividuals();

		while (individuals.hasNext()) {
			Resource individual = individuals.next();
			list.add(new OntoResource(individual.getLocalName(), individual
					.getURI()));
		}
		return list;
	}

	public List<OntoResource> getAllClasses() {
		List<OntoResource> list = new ArrayList<OntoResource>();
		ExtendedIterator<OntClass> iter = m.listClasses();
		while (iter.hasNext()) {
			OntClass node = iter.next();
			list.add(new OntoResource(node.getLocalName(), node.getURI()));
			// OntClass hierarchy = iter.next();
			// recursiveThroughOntologyToGetClass(list, hierarchy);
		}
		return list;
	}

	public List<OntoResource> getClassFromInstance(String instance) {
		List<OntoResource> list = new ArrayList<OntoResource>();
		Individual node = m.getIndividual(SystemConstant.NS + instance);

		ExtendedIterator<OntClass> iter = node.listOntClasses(true);
		while (iter.hasNext()) {
			try {
				OntClass hierarchy = iter.next();
				list.add(new OntoResource(hierarchy.getLocalName(), hierarchy
						.getURI()));
			} catch (Exception e) {
				continue;
			}
		}

		return list;
	}

	public List<OntoResource> getClassesFromClass(String className) {
		List<OntoResource> list = new ArrayList<OntoResource>();
		OntClass node = m.getOntClass(SystemConstant.NS + className);

		ExtendedIterator<OntClass> iter = node.listSubClasses(true);
		if (node.hasSubClass()) {
			while (iter.hasNext()) {
				OntClass hierarchy = iter.next();
				recursiveThroughOntologyToGetClass(list, hierarchy);
			}
		}

		return list;
	}

	public List<OntoResource> getInstanceFromClass(String className) {
		List<OntoResource> list = new ArrayList<OntoResource>();
		OntClass node = m.getOntClass(SystemConstant.NS + className);

		@SuppressWarnings("unchecked")
		ExtendedIterator<Individual> individuals = (ExtendedIterator<Individual>) node
				.listInstances();

		while (individuals.hasNext()) {
			Resource individual = individuals.next();
			list.add(new OntoResource(individual.getLocalName(), individual
					.getURI()));
		}

		if (node.hasSubClass()) {
			ExtendedIterator<OntClass> iter = node.listSubClasses(true);
			while (iter.hasNext()) {
				OntClass hierarchy = iter.next();
				recursiveThroughOntologyToGetIntance(list, hierarchy);
			}
		}

		return list;
	}

	private void recursiveThroughOntologyToGetClass(List<OntoResource> list,
			OntClass node) {
		list.add(new OntoResource(node.getLocalName(), node.getURI()));
		if (node.hasSubClass()) {
			ExtendedIterator<OntClass> iter = node.listSubClasses(true);
			while (iter.hasNext()) {
				OntClass hierarchy = iter.next();
				recursiveThroughOntologyToGetClass(list, hierarchy);
			}
		}
	}

	private void recursiveThroughOntologyToGetIntance(List<OntoResource> list,
			OntClass node) {
		@SuppressWarnings("unchecked")
		ExtendedIterator<Individual> individuals = (ExtendedIterator<Individual>) node
				.listInstances();

		while (individuals.hasNext()) {
			Resource individual = individuals.next();
			list.add(new OntoResource(individual.getLocalName(), individual
					.getURI()));
		}

		if (node.hasSubClass()) {
			ExtendedIterator<OntClass> iter = node.listSubClasses(true);
			while (iter.hasNext()) {
				OntClass hierarchy = iter.next();
				recursiveThroughOntologyToGetIntance(list, hierarchy);
			}
		}
	}

	public String getManufacturer(String instance) {
		String manufacturer = "";
		OntProperty hasManufacturer = m.getOntProperty(SystemConstant.NS
				+ "hasManufacturer");
		Individual node = m.getIndividual(SystemConstant.NS + instance);

		manufacturer = node.getPropertyValue(hasManufacturer).toString();
		manufacturer = getNameFromUri(manufacturer);
		return manufacturer;
	}

	public static String getNameFromUri(String uri) {
		return uri.replace(SystemConstant.NS, "");
	}

	public static String getClearName(String name) {
		String result = name.replace("_", " ");
		return result;
	}
	
	public void reset() {
		m.removeAll();
		m.close();
		m.reset();
		FileManager.get().resetCache();
		m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		FileManager.get().readModel(m, SystemConstant.O_FILE);
	}
	
	public static void main(String[] args) {
		OntoQuery ontoQuery = new OntoQuery();
		 //List<OntoResource> list = ontoQuery.getClassFromInstance("LG_32CS460");
		 List<OntoResource> list = ontoQuery.getAllInstance();
		 System.out.println(list.size() - ontoQuery.getInstanceFromClass("Manufacturer").size());
		 System.out.println(list);
	}

}
